package hw.ats.news.ds;

import hw.ats.news.model.News;

import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.util.ByteArrayBuffer;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import com.humanwares.util.StringUtil;

public class NewsParser {
	
	public List<News> parse(String urlstring) {
		List<News> results = null;
        try {
            URL url = new URL(urlstring);
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();

            long startTime = System.currentTimeMillis();
            
            URLConnection con = url.openConnection();
            InputStream is = con.getInputStream();
            ByteArrayBuffer bab = new ByteArrayBuffer(1000);
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = is.read(b)) != -1) {
            	bab.append(b, 0, len);
            }
                        
            
            String xml = new String(bab.toByteArray(), "UTF-8");
            XmlHandler handler = new XmlHandler();
            xr.setContentHandler(handler);
            xr.parse(new InputSource(new StringReader(xml)));
            results = handler.getItems();
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        if (results == null) {
        	results = new ArrayList<News>();
        }
        
        return results;
	}
	
	class XmlHandler extends DefaultHandler {
	    private static final String ITEM = "entry";
	    private static final String UID = "id";
	    private static final String THUMB = "thumbnail"; // name=default, name=list
	    private static final String MOVIE = "youtube";
	    private static final String TITLE = "title";
	    private static final String REGDATE = "written";
	    private static final String DATA = "summary";
	    private static final String BODY_HTML = "content";
	    private static final String CATEGORY = "category"; // id=
	    private static final String AUTHOR = "author";
	    private static final String MAIN_IMAGE = "main_image"; //
	    private static final String CMT_CNT = "comments";
	    //private static final String CMT_CNT = "cmt_cnt";
	    //private static final String RECMD_FLAG = "recmd_flag";
	    private static final String URL = "permalink";
	    
	    // audio
	    private static final String AUDIO = "audio";
	    private static final String SIZE = "size";
	    private static final String PLAYTIME = "playtime";

	    private boolean startEntry = false;
	    private News item = null;
	    private StringBuilder buf = null;
		private final ArrayList<News> items;
		private String thumbType = null;
		
	    public XmlHandler() {
	        items = new ArrayList<News>();
	        buf = new StringBuilder();
	    }
	    
	    @Override
	    public void startDocument() throws SAXException {
	    }
	  
	    @Override
	    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) 
	    throws SAXException {
	        if (localName.equals(XmlHandler.ITEM)) {
	            startEntry = true;
	            item = new News();
	            buf.setLength(0);
	        }
	        
	        if (this.startEntry && localName.equals(XmlHandler.CATEGORY)) {
	        	String uid = getAttributeValue("id", atts);
	        	item.cate_uid = Integer.parseInt(uid);
	        } else if (this.startEntry && localName.equals(XmlHandler.THUMB)) {
	        	thumbType = getAttributeValue("name", atts);
	        } else if (this.startEntry && localName.equals(XmlHandler.AUDIO)) {
	        	item.mp3_fileSize = Long.parseLong(getAttributeValue(XmlHandler.SIZE, atts));
	        	item.mp3_totalDuration = Long.parseLong(getAttributeValue(XmlHandler.PLAYTIME, atts));
	        }
	    }
	    
	    @Override
	    public void endDocument() throws SAXException {
	    }

	    @Override
	    public void endElement(String namespaceURI, String localName, String qName) 
	    throws SAXException {
	        if (localName.equals(XmlHandler.ITEM)) {
	            startEntry = false;
	            if (item.url == null) item.url = "N"+item.uid;
	            if (item.body_html == null) item.body_html = "";
	            if (item.body_text == null) item.body_text = "";
	            if (item.mp3_url == null) item.mp3_url = "";
	            items.add(item);
	            item = new News();
	            thumbType = null;
	        }

	        if (startEntry) {
	            if (localName.equals(XmlHandler.UID)) {
	            	item.uid = Integer.parseInt(buf.toString().trim());
	            } else if (localName.equals(XmlHandler.THUMB)) {
		        	if ("default".equals(thumbType)) {
		        		item.thumb_default = buf.toString().trim();
		        	} else if ("list".equals(thumbType)) {
		        		item.thumb_list = buf.toString().trim();
		        	}
	            	if (item.thumb_default != null && item.thumb_default.length() > 0)
	            		item.photo_flag = true;
	            } else if (localName.equals(XmlHandler.MOVIE)) {
	            	item.movie = buf.toString().trim();
	            	if (item.movie != null && item.movie.length() > 0)
	            		item.movie_flag = true;
	            	else
	            		item.movie_flag = false;
	            } else if (localName.equals(XmlHandler.MAIN_IMAGE)) {
	            	item.main_image = buf.toString().trim();
//	            	if (item.main_image != null && item.main_image.length() > 0)
//	            		item.recmd_flag = true;
	            } else if (localName.equals(XmlHandler.TITLE)) {
	            	item.title = buf.toString().trim().replaceAll("&nbsp;", " ");
	            } else if (localName.equals(XmlHandler.REGDATE)) {
	            	item.regdate = new Date(StringUtil.longValue(buf.toString().trim()) * 1000L);
	            } else if (localName.equals(XmlHandler.DATA)) {
	            	item.body_text = buf.toString().replaceAll("&nbsp;", " ").trim();
	            } else if (localName.equals(XmlHandler.BODY_HTML)) {
	            	item.body_html = buf.toString().trim();
	            } else if (localName.equals(XmlHandler.CATEGORY)) {
	            	item.cate_name = buf.toString().trim();
	            } else if (localName.equals(XmlHandler.AUTHOR)) {
	            	item.author = buf.toString().trim();
	            } else if (localName.equals(XmlHandler.CMT_CNT)) {
	            	item.cmt_cnt = StringUtil.intValue(buf.toString().trim(), 0);
//	            } else if (localName.equals(XmlHandler.RECMD_FLAG)) {
//	            	item.recmd_flag = Integer.parseInt(buf.toString().trim()) > 0;
	            } else if (localName.equals(XmlHandler.URL)) {
	            	item.url = buf.toString().trim();
	            } else if (localName.equals(XmlHandler.AUDIO)) {
	            	item.mp3_url = buf.toString().trim();
	            }
	            
	            buf.setLength(0);
	        }
	    }   
	    
	    @Override
	    public void characters(char[] ch, int start, int length) {
	        if (ch != null) {
	            buf.append(new String(ch, start, length));
	        }
	    }
	    
	    public ArrayList<News> getItems() {
	        return items;
	    }
	    
	    private String getAttributeValue(String attName, Attributes atts) {
	    	
	        String result = null;
	        for (int i = 0; i < atts.getLength(); i++) {
	            String thisAtt = atts.getLocalName(i);
	            if (attName.equals(thisAtt)) {
	                result = atts.getValue(i);
	                break;
	            }
	        }
	        
	        return result;
	    }
	}
}
